package com.tianhao.luo.aspect;

import com.tianhao.luo.annotation.UserFileRecodeAnnotation;
import com.tianhao.luo.domain.entity.HiamUser;
import com.tianhao.luo.service.UserFileService;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;

import java.lang.reflect.Method;
import java.util.Date;

/**
 * @ClassName: UserFileRecodeAdvice
 * @Description: 用户文件记录的aop实现
 * @author: tianhao.luo@hand-china.com
 * @date: 2020/8/10  8:43
 */
@Aspect
@Component
public class UserFileRecodeAdvice {
    private static final Logger LOGGER = LoggerFactory.getLogger(UserFileRecodeAdvice.class);

    @Autowired
    private UserFileService userFileService;

    private ProceedingJoinPoint joinPoint;


    @Pointcut("@annotation(com.tianhao.luo.annotation.UserFileRecodeAnnotation)")
    public void userFileRecode() {

    }

    @Around("userFileRecode()")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        this.setJoinPoint(joinPoint);
        return joinPoint.proceed();
    }

    @After("userFileRecode()")
    public void after() throws Exception {
        Method api = getCurrentMethod(joinPoint);
        api.setAccessible(true);
        UserFileRecodeAnnotation userFileRecodeAnnotation = api.getAnnotation(UserFileRecodeAnnotation.class);
        HiamUser hiamUser = new HiamUser();
        String uuid = null;
        if (userFileRecodeAnnotation.value()) {
            Object[] args = joinPoint.getArgs();
            for (Object obj :
                    args) {
                if (obj instanceof HiamUser) {
                    hiamUser = (HiamUser) obj;
                } else if (obj instanceof String) {
                    uuid = (String) obj;
                }
            }
            if (!ObjectUtils.isEmpty(userFileService.queryFileByUserAndUuid(hiamUser, uuid))) {
                userFileService.insertRecode(hiamUser, uuid, new Date());
                LOGGER.info("成功记录用户下载文件记录");
            }
        }
    }

    @AfterReturning(pointcut = "userFileRecode()", returning = "result")
    public void afterReturn(Object result) {

    }

    /**
     * 获取当前注解所注解的方法；joinPoint就是连接点，指的就是注解的方法体
     * 1. 通过连接点获取MethodSignature
     * 2. 通过连接点获取目标对象，该对象就是所注解的类的对象
     * 3. 通过该目标类对象来反射该类，再获取其中被注解所注解的方法
     *
     * @param joinPoint 连接点
     * @return ResponseResult注解的方法
     */
    private Method getCurrentMethod(ProceedingJoinPoint joinPoint) throws NoSuchMethodException {
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Object target = joinPoint.getTarget();
        return target.getClass().getDeclaredMethod(signature.getName(), signature.getParameterTypes());
    }

    public ProceedingJoinPoint getJoinPoint() {
        return joinPoint;
    }

    public void setJoinPoint(ProceedingJoinPoint joinPoint) {
        this.joinPoint = joinPoint;
    }
}
